package com.dap.configsvrclient.disconf.rest;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.text.MessageFormat;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import com.alibaba.fastjson.JSON;
import com.dap.configsvrclient.util.ConfigSvrConfig;
import com.dap.core.context.ContextUtils;


public class DisconfRestMgr {
    private static final String DISCONF_WEB_ZK_HOST_URL = "/api/zoo/hosts";
    private static final String DISCONF_CONFIG_FILE_URL =
            "/api/configExtension/file?app={0}&env={1}&type=0&key={2}&version={3}&bankKey={4}";
    private static final String DISCONF_ZK_PREFIX_URL = "/api/zoo/prefix";
    private static final Logger LOGGER = LoggerFactory.getLogger(DisconfRestMgr.class);
    private static final DisconfRestMgr instance = new DisconfRestMgr();
    private String prefix;


    public static DisconfRestMgr getInstance() {
        return instance;
    }


    private InputStream retrieveFromDisconfWeb(String configUrl) {
        Assert.notNull(configUrl);
        if (!ConfigSvrConfig.getInstance().isEnable()) {
            return null;
        }
        try {
            configUrl = configUrl.trim();
            if ((!configUrl.startsWith("/")) && (!configUrl.startsWith("\\"))) {
                configUrl = "/" + configUrl;
            }
            URL url = new URL(ConfigSvrConfig.getInstance().getConfigSvrHost() + configUrl);
            URLConnection conn = url.openConnection();
            return conn.getInputStream();
        } catch (Exception e) {
            LOGGER.error(e.toString(), e);
        }
        return null;
    }


    public String retrieveZkHost() {
        return retrieveValueFromDisconf(DISCONF_WEB_ZK_HOST_URL);
    }


    private String retrieveValueFromDisconf(String url) {
        InputStream is = retrieveFromDisconfWeb(url);
        if (is == null) {
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            int b = 0;
            while ((b = is.read()) != -1) {
                baos.write(b);
            }

            @SuppressWarnings("unchecked")
            Map<String, Object> map = JSON.parseObject(baos.toString(), Map.class);
            if (1 == ((Integer) map.get("status")).intValue()) {
                return (String) map.get("value");
            }
        } catch (IOException e) {
            LOGGER.error(e.toString(), e);
        } finally {
            try {
                baos.close();
                is.close();
            } catch (IOException e) {
                LOGGER.error(e.toString(), e);
            }
        }
        return null;
    }


    public InputStream retrieveConfig(String configKey) {
        Assert.notNull(configKey);
        String configUrl = assembleUrl(configKey);
        return retrieveFromDisconfWeb(configUrl);
    }


    public String assembleUrl(String configKey) {
        MessageFormat mf = new MessageFormat(DISCONF_CONFIG_FILE_URL);
        return mf.format(new Object[] { ConfigSvrConfig.getInstance().getAppName(), ConfigSvrConfig.getInstance().getEnv(), configKey,
                                        ConfigSvrConfig.getInstance().getVersion(), ContextUtils.getTenantId() });
    }


    public String retrieveZkPrefix() {
        if (this.prefix == null) {
            this.prefix = retrieveValueFromDisconf(DISCONF_ZK_PREFIX_URL);
        }
        return this.prefix;
    }
}
